package com.foton.bpc.all.remoting.rpc.impl;

import com.foton.bpc.all.remoting.Client;
import com.foton.bpc.all.remoting.Transport;
import com.foton.bpc.all.remoting.dto.BpcInvacation;
import com.foton.bpc.all.remoting.dto.Response;
import com.foton.bpc.all.remoting.invoker.Invoker;
import com.foton.bpc.all.remoting.invoker.impl.BpcClientInvoker;
import com.foton.bpc.all.remoting.netty.codec.impl.BpcCodec;
import com.foton.bpc.all.remoting.netty.handler.BpcClientHandler;
import com.foton.bpc.all.remoting.netty.handler.BpcServerHandler;
import com.foton.bpc.all.remoting.rpc.Protocol;
import com.foton.bpc.all.serialzation.Serialzation;
import com.foton.bpc.all.serialzation.json.JsonSerialzation;
import com.foton.bpc.all.util.SpIUtils;
import com.foton.bpc.all.util.URIUtils;

import java.net.URI;

/**
 * @Author RenPu
 * @Date 2023/6/6 16:05
 * @Version 1.0
 * @Description: 协议实现类
 **/
public class BpcProtocol implements Protocol {


    /**
     * 1：通过获取配置得协议配置
     * 2：通过SPI机制加载对应得实现类
     * 3:启动网络服务
     * @param uri
     */
    @Override
    public void export(URI uri, Invoker invoker) {


        //根据配置选择底序列化具体实现得方式：例如：fastJson,jackSon
        Serialzation serialzation=(Serialzation)SpIUtils.
                getServiceImpl("JsonSerialzation", Serialzation.class);
        
        //1:编解码器
        BpcCodec bpcCodec = new BpcCodec();
        bpcCodec.setDecodeType(BpcInvacation.class);
        bpcCodec.setSerialzation(serialzation);

        //2:设置BpcServerHandler(收到请求处理器)
        BpcServerHandler handler = new BpcServerHandler();
        handler.setInvoker(invoker);
        handler.setSerialzation(serialzation);

        //根据配置选择底层网络通信框架：例如：netty,mina
        String transportName = URIUtils.getParam(uri, "transport");
        Transport transport =(Transport) SpIUtils.getServiceImpl(transportName, Transport.class);
        transport.start(uri,bpcCodec,handler);

    }


    /**
     * 服务调用所需得方法（服务调用者）
     * @return
     */
    @Override
    public Invoker refer(URI consumerUri) {

        //序列化
        //根据配置选择底序列化具体实现得方式：例如：fastJson,jackSon
        Serialzation serialzation=(Serialzation)SpIUtils.
                getServiceImpl("JsonSerialzation", Serialzation.class);

        //编解码器
        BpcCodec bpcCodec = new BpcCodec();
        bpcCodec.setSerialzation(serialzation);
        bpcCodec.setDecodeType(Response.class);

        //接收响应处理
        BpcClientHandler bpcClientHandler = new BpcClientHandler();

        //长连接  链接
        String transportName = URIUtils.getParam(consumerUri, "transport");
        Transport transport =(Transport) SpIUtils.getServiceImpl(transportName, Transport.class);
        Client client = transport.connect(consumerUri, bpcCodec, bpcClientHandler);

        //通过网络链接发送数据
        BpcClientInvoker bpcClientInvoker = new BpcClientInvoker(client,serialzation);

        return bpcClientInvoker;
    }
}
